﻿using System;

namespace Microsoft.Popfly.GameCreator.GameEngine.Behaviors
{
    public class SimpleXAccelerationMove : XMoveBehavior
    {
        public SimpleXAccelerationMove(BehaviorOwner owner, double acceleration) : base(owner, acceleration){}


        #region Behavior Members

        public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
        {
            m_owner.XAcceleration += m_offset;
        }

        #endregion
    }

    public class SimpleYAccelerationMove : YMoveBehavior
    {
        public SimpleYAccelerationMove(BehaviorOwner owner, double acceleration) : base(owner, acceleration) {}


        #region Behavior Members

        public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
        {
            m_owner.YAcceleration += m_offset;
        }

        #endregion
    }

    public class SimpleXYAccelerationMove : XYMoveBehavior
    {
        private double m_XAcceleration;
        private double m_YAcceleration;

        private static double sqrtOfTwoOverTwo = Math.Sqrt(2) / 2.0;

        public SimpleXYAccelerationMove(BehaviorOwner owner, double accelerationMagnitude, Data.MotionInfo.DirectionValues direction) : base(owner, accelerationMagnitude)
        {
            switch (direction)
            {
                case Data.MotionInfo.DirectionValues.NE:
                    m_XAcceleration = sqrtOfTwoOverTwo;
                    m_YAcceleration = -sqrtOfTwoOverTwo;
                    break;
                case Data.MotionInfo.DirectionValues.NW:
                    m_XAcceleration = -sqrtOfTwoOverTwo;
                    m_YAcceleration = -sqrtOfTwoOverTwo;
                    break;
                case Data.MotionInfo.DirectionValues.SE:
                    m_XAcceleration = sqrtOfTwoOverTwo;
                    m_YAcceleration = sqrtOfTwoOverTwo;
                    break;
                case Data.MotionInfo.DirectionValues.SW:
                    m_XAcceleration = -sqrtOfTwoOverTwo;
                    m_YAcceleration = sqrtOfTwoOverTwo;
                    break;
                default:
                    throw new ArgumentException(
                        Utils.ErrorMessagePrefix + "SimpleXYMove is only for direction values of NE, NW, SE or SW.  '" +
                        direction.ToString() + "' was passed in instead.");
            }
            m_XAcceleration *= accelerationMagnitude;
            m_YAcceleration *= accelerationMagnitude;
        }

        #region Behavior Members

        public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
        {
            if (m_isOriginalDirection)
            {
                m_owner.YAcceleration += m_YAcceleration;
                m_owner.XAcceleration += m_XAcceleration;
            }
            else
            {
                m_owner.YAcceleration -= m_YAcceleration;
                m_owner.XAcceleration -= m_XAcceleration;
            }
        }

        #endregion
    }

    public class SimpleAccelerationRotation : RotateBehavior
    {
        private Actor m_actorOwner;

        public SimpleAccelerationRotation(Actor owner, double acceleration) : base (owner, acceleration)
        {
            m_actorOwner = owner;

        }

        public SimpleAccelerationRotation(Actor owner, Data.MotionInfo rotationInfo) : base(owner, rotationInfo.Acceleration)
        {
            if (rotationInfo.Relative != Data.MotionInfo.RelativeValues.Self)
            {
                throw new ArgumentException(
                    Utils.ErrorMessagePrefix + 
                    "SimpleRotation only knows how to handle clockwise/counterclockwise motions relative to self.  '" 
                    + rotationInfo.Relative.ToString() + "' was passed in."
                    );
            }

            m_actorOwner = owner;

            switch (rotationInfo.Direction)
            {
                case Data.MotionInfo.DirectionValues.E:
                    m_offset = - m_offset;
                    break;
                case Data.MotionInfo.DirectionValues.W:
                    break;
                default:
                    throw new ArgumentException(
                        Utils.ErrorMessagePrefix + 
                        "SimpleRotation only understands E for counter clockwise and W for clockwise.  '" + 
                        rotationInfo.Direction.ToString() + "' was passed in."
                        );
            }
        }

        #region Behavior Members

        public override void Invoke(BehaviorOwner sender, Events.PGCEventArgs args)
        {
            m_actorOwner.RotationAcceleration += m_offset;
        }

        #endregion
    }
}
